/**
 * onbeforeunload 事件在即将离开当前页面（刷新或关闭）时触发。
 * */
export function onBeforeunload(callback) {
    window.addEventListener('beforeunload', callback, true)
}
/**
 *  页面是否从浏览器缓存中读取，比如前进、后退等。
 **/
export function onCachePageshow(callback) {
    window.addEventListener('pageshow', event => {
        if (event.persisted) {
            callback(event)
        }
    }, true)
}

/**
 * 监听页面隐藏事件。
 * pagehide: 浏览器窗口关闭时触发、后退、前进到其他页面时触发。
 * visibilitychange: 浏览器窗口最小化、切换到其他标签页、切换到其他应用时触发。
 * */
export function onHidden(callback, once) {
    const onHiddenOrPageHide = (event) => {
        if (event.type === 'pagehide' || document.visibilityState === 'hidden') {
            callback(event)
            if (once) {
                window.removeEventListener('visibilitychange', onHiddenOrPageHide, true)
                window.removeEventListener('pagehide', onHiddenOrPageHide, true)
            }
        }
    }
    
    window.addEventListener('visibilitychange', onHiddenOrPageHide, true)
    window.addEventListener('pagehide', onHiddenOrPageHide, true)
}
export function deepCopy(target) {
    if (typeof target === 'object') {
        const result = Array.isArray(target) ? [] : {}
        for (const key in target) {
            if (typeof target[key] == 'object') {
                result[key] = deepCopy(target[key])
            } else {
                result[key] = target[key]
            }
        }

        return result
    }

    return target
}
/**
 * 表示文档及其所有资源（如图像、样式表等）已完全加载时，监听性能数据。
 * load：当整个页面（包括所有依赖的资源，如图像、样式表等）完全加载后触发。，监听性能数据。
 * */
export function onAfterLoad(callback) {
    if (document.readyState === 'complete') {
        callback()
    } else {
        const onLoad = () => {
            callback()
            // onload 事件只会触发一次，所以可以移除监听器
            window.removeEventListener('load', onLoad, true)
        }

        window.addEventListener('load', onLoad, true)
    }
}
// 获取当前页面URL
export function getPagePath() {
    return window.location.href
}
/**
 * 路径数组生成选择器字符串
 * */
function selectorStr(path) {
    // 反转路径数组，并过滤掉 window 和 document 元素
    return path.reverse().filter(element => {
        return element !== window && element !== document;
    }).map((element) => {
        // 根据元素的属性生成选择器字符串
        if (element.id) {
            return `${element.tagName.toLowerCase()}#${element.id}`;
        } else if (element.className && typeof element.className === 'string') {
            return `${element.nodeName.toLowerCase()}.${element.className}`;
        } else {
            return element.nodeName.toLowerCase();
        }
    }).join(' '); // 将选择器字符串连接起来并返回
}
/**
 * 根据路径数组或目标元素生成选择器字符串
 * */
export function getSelector(pathsOrTarget) {
    if (Array.isArray(pathsOrTarget)) { // 如果传入的是路径数组
        return selectorStr(pathsOrTarget); // 调用 getSelectors 函数生成选择器字符串并返回
    } else { // 如果传入的是目标元素
        let path = [];
        while (pathsOrTarget) { // 循环遍历目标元素的父节点，将其添加到路径数组中
            path.push(pathsOrTarget);
            pathsOrTarget = pathsOrTarget.parentNode;
        }
        return selectorStr(path); // 调用 getSelectors 函数生成选择器字符串并返回
    }
}

/**
 * 获取栈堆信息
 * */
export function getStack(stack) {
    return stack.split('\n').slice(1).map(item => item.replace(/^\s+at\s+/g, "")).join('^')
}

/**
 * PerformanceObserver API 是否支持
 * */
export function isSupportPerformanceObserver() {
    return !!window.PerformanceObserver
}

/**
 * 保存原始 XMLHttpRequest 对象信息
 * */
export const xhrPrototype = XMLHttpRequest.prototype;
export const xhrOpen = xhrPrototype.open
export const xhrSend = xhrPrototype.send

/**
 * navigator?.sendBeacon API 是否支持
 * */
export function isSupportSendBeacon() {
    return !!window.navigator?.sendBeacon
}
